<!-- HTML header for doxygen 1.8.6-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<title>OpenCV: Build OpenCV.js</title>
<link href="../../opencv.ico" rel="shortcut icon" type="image/x-icon" />
<link href="../../tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../jquery.js"></script>
<script type="text/javascript" src="../../dynsections.js"></script>
<script type="text/javascript" src="../../tutorial-utils.js"></script>
<link href="../../search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="../../search/searchdata.js"></script>
<script type="text/javascript" src="../../search/search.js"></script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js", "TeX/AMSmath.js", "TeX/AMSsymbols.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
//<![CDATA[
MathJax.Hub.Config(
{
  TeX: {
      Macros: {
          matTT: [ "\\[ \\left|\\begin{array}{ccc} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{array}\\right| \\]", 9],
          fork: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ \\end{array} \\right.", 4],
          forkthree: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ \\end{array} \\right.", 6],
          forkfour: ["\\left\\{ \\begin{array}{l l} #1 & \\mbox{#2}\\\\ #3 & \\mbox{#4}\\\\ #5 & \\mbox{#6}\\\\ #7 & \\mbox{#8}\\\\ \\end{array} \\right.", 8],
          vecthree: ["\\begin{bmatrix} #1\\\\ #2\\\\ #3 \\end{bmatrix}", 3],
          vecthreethree: ["\\begin{bmatrix} #1 & #2 & #3\\\\ #4 & #5 & #6\\\\ #7 & #8 & #9 \\end{bmatrix}", 9],
          cameramatrix: ["#1 = \\begin{bmatrix} f_x & 0 & c_x\\\\ 0 & f_y & c_y\\\\ 0 & 0 & 1 \\end{bmatrix}", 1],
          distcoeffs: ["(k_1, k_2, p_1, p_2[, k_3[, k_4, k_5, k_6 [, s_1, s_2, s_3, s_4[, \\tau_x, \\tau_y]]]]) \\text{ of 4, 5, 8, 12 or 14 elements}"],
          distcoeffsfisheye: ["(k_1, k_2, k_3, k_4)"],
          hdotsfor: ["\\dots", 1],
          mathbbm: ["\\mathbb{#1}", 1],
          bordermatrix: ["\\matrix{#1}", 1]
      }
  }
}
);
//]]>
</script><script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>
<link href="../../doxygen.css" rel="stylesheet" type="text/css" />
<link href="../../stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<!--#include virtual="/google-search.html"-->
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectlogo"><img alt="Logo" src="../../opencv-logo-small.png"/></td>
  <td style="padding-left: 0.5em;">
   <div id="projectname">OpenCV
   &#160;<span id="projectnumber">4.5.2</span>
   </div>
   <div id="projectbrief">Open Source Computer Vision</div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript">
var searchBox = new SearchBox("searchBox", "../../search",false,'Search');
</script>
<script type="text/javascript" src="../../menudata.js"></script>
<script type="text/javascript" src="../../menu.js"></script>
<script type="text/javascript">
$(function() {
  initMenu('../../',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="../../d5/d10/tutorial_js_root.html">OpenCV.js Tutorials</a></li><li class="navelem"><a class="el" href="../../df/df7/tutorial_js_table_of_contents_setup.html">Introduction to OpenCV.js</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">Build OpenCV.js </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><dl class="section note"><dt>Note</dt><dd>You don't have to build your own copy if you simply want to start using it. Refer the Using Opencv.js tutorial for steps on getting a prebuilt copy from our releases or online documentation.</dd></dl>
<h2>Installing Emscripten </h2>
<p><a href="https://github.com/emscripten-core/emscripten">Emscripten</a> is an LLVM-to-JavaScript compiler. We will use Emscripten to build OpenCV.js.</p>
<dl class="section note"><dt>Note</dt><dd>While this describes installation of required tools from scratch, there's a section below also describing an alternative procedure to perform the same build using docker containers which is often easier.</dd></dl>
<p>To Install Emscripten, follow instructions of <a href="https://emscripten.org/docs/getting_started/downloads.html">Emscripten SDK</a>.</p>
<p>For example: </p><div class="fragment"><div class="line">./emsdk update</div><div class="line">./emsdk install latest</div><div class="line">./emsdk activate latest</div></div><!-- fragment --><p>After install, ensure the <code>EMSDK</code> environment is setup correctly.</p>
<p>For example: </p><div class="fragment"><div class="line">source ./emsdk_env.sh</div><div class="line">echo ${EMSDK}</div></div><!-- fragment --><p>Modern versions of Emscripten requires to use <code>emcmake</code> / <code>emmake</code> launchers:</p>
<div class="fragment"><div class="line">emcmake sh -c &#39;echo ${EMSCRIPTEN}&#39;</div></div><!-- fragment --><p>The version 2.0.10 of emscripten is verified for latest WebAssembly. Please check the version of Emscripten to use the newest features of WebAssembly.</p>
<p>For example: </p><div class="fragment"><div class="line">./emsdk update</div><div class="line">./emsdk install 2.0.10</div><div class="line">./emsdk activate 2.0.10</div></div><!-- fragment --><h2>Obtaining OpenCV Source Code </h2>
<p>You can use the latest stable OpenCV version or you can grab the latest snapshot from our <a href="https://github.com/opencv/opencv.git">Git repository</a>.</p>
<h3>Obtaining the Latest Stable OpenCV Version</h3>
<ul>
<li>Go to our <a href="http://opencv.org/releases.html">releases page</a>.</li>
<li>Download the source archive and unpack it.</li>
</ul>
<h3>Obtaining the Cutting-edge OpenCV from the Git Repository</h3>
<p>Launch Git client and clone <a href="http://github.com/opencv/opencv">OpenCV repository</a>.</p>
<p>For example: </p><div class="fragment"><div class="line">git clone https://github.com/opencv/opencv.git</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>It requires <code>git</code> installed in your development environment.</dd></dl>
<h2>Building OpenCV.js from Source </h2>
<ol type="1">
<li><p class="startli">To build <code>opencv.js</code>, execute python script <code>&lt;opencv_src_dir&gt;/platforms/js/build_js.py &lt;build_dir&gt;</code>.</p>
<p class="startli">For example, to build in <code>build_js</code> directory: </p><div class="fragment"><div class="line">emcmake python ./opencv/platforms/js/build_js.py build_js</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>It requires <code>python</code> and <code>cmake</code> installed in your development environment.</dd></dl>
</li>
<li><p class="startli">The build script builds asm.js version by default. To build WebAssembly version, append <code>--build_wasm</code> switch.</p>
<p class="startli">For example, to build wasm version in <code>build_wasm</code> directory: </p><div class="fragment"><div class="line">emcmake python ./opencv/platforms/js/build_js.py build_wasm --build_wasm</div></div><!-- fragment --></li>
<li><p class="startli">[Optional] To build the OpenCV.js loader, append <code>--build_loader</code>.</p>
<p class="startli">For example: </p><div class="fragment"><div class="line">emcmake python ./opencv/platforms/js/build_js.py build_js --build_loader</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>The loader is implemented as a js file in the path <code>&lt;opencv_js_dir&gt;/bin/loader.js</code>. The loader utilizes the <a href="https://github.com/GoogleChromeLabs/wasm-feature-detect">WebAssembly Feature Detection</a> to detect the features of the broswer and load corresponding OpenCV.js automatically. To use it, you need to use the UMD version of <a href="https://github.com/GoogleChromeLabs/wasm-feature-detect">WebAssembly Feature Detection</a> and introduce the <code>loader.js</code> in your Web application.</dd></dl>
<p>Example Code: </p><div class="fragment"><div class="line">// Set paths configuration</div><div class="line">let pathsConfig = {</div><div class="line">    wasm: &quot;../../build_wasm/opencv.js&quot;,</div><div class="line">    threads: &quot;../../build_mt/opencv.js&quot;,</div><div class="line">    simd: &quot;../../build_simd/opencv.js&quot;,</div><div class="line">    threadsSimd: &quot;../../build_mtSIMD/opencv.js&quot;,</div><div class="line">}</div><div class="line"></div><div class="line">// Load OpenCV.js and use the pathsConfiguration and main function as the params.</div><div class="line">loadOpenCV(pathsConfig, main);</div></div><!-- fragment --></li>
<li><p class="startli">[optional] To build documents, append <code>--build_doc</code> option.</p>
<p class="startli">For example: </p><div class="fragment"><div class="line">emcmake python ./opencv/platforms/js/build_js.py build_js --build_doc</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>It requires <code>doxygen</code> installed in your development environment.</dd></dl>
</li>
<li><p class="startli">[optional] To build tests, append <code>--build_test</code> option.</p>
<p class="startli">For example: </p><div class="fragment"><div class="line">emcmake python ./opencv/platforms/js/build_js.py build_js --build_test</div></div><!-- fragment --></li>
<li><p class="startli">[optional] To enable OpenCV contrib modules append <code>--cmake_option="-DOPENCV_EXTRA_MODULES_PATH=/path/to/opencv_contrib/modules/"</code></p>
<p class="startli">For example: </p><div class="fragment"><div class="line">python ./platforms/js/build_js.py build_js --cmake_option=&quot;-DOPENCV_EXTRA_MODULES_PATH=opencv_contrib/modules&quot;</div></div><!-- fragment --></li>
<li><p class="startli">[optional] To enable OpenCV contrib modules append <code>--cmake_option="-DOPENCV_EXTRA_MODULES_PATH=/path/to/opencv_contrib/modules/"</code></p>
<p class="startli">For example: </p><div class="fragment"><div class="line">python ./platforms/js/build_js.py build_js --cmake_option=&quot;-DOPENCV_EXTRA_MODULES_PATH=opencv_contrib/modules&quot;</div></div><!-- fragment --></li>
</ol>
<h2>Running OpenCV.js Tests </h2>
<p>Remember to launch the build command passing <code>--build_test</code> as mentioned previously. This will generate test source code ready to run together with <code>opencv.js</code> file in <code>build_js/bin</code></p>
<h3>Manually in your browser</h3>
<p>To run tests, launch a local web server in <code>\&lt;build_dir\&gt;/bin</code> folder. For example, node http-server which serves on <code>localhost:8080</code>.</p>
<p>Navigate the web browser to <code><a href="http://localhost:8080/tests.html">http://localhost:8080/tests.html</a></code>, which runs the unit tests automatically. Command example:</p>
<div class="fragment"><div class="line">npx http-server build_js/bin</div><div class="line">firefox http://localhost:8080/tests.html</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>This snippet and the following require <a href="https://nodejs.org">Node.js</a> to be installed.</dd></dl>
<h3>Headless with Puppeteer</h3>
<p>Alternatively tests can run with <a href="https://github.com/GoogleChrome/puppeteer#readme">GoogleChrome/puppeteer</a> which is a version of Google Chrome that runs in the terminal (useful for Continuos integration like travis CI, etc)</p>
<div class="fragment"><div class="line">cd build_js/bin</div><div class="line">npm install</div><div class="line">npm install --no-save puppeteer    # automatically downloads Chromium package</div><div class="line">node run_puppeteer.js</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>Checkout <code>node run_puppeteer --help</code> for more options to debug and reporting.</dd>
<dd>
The command <code>npm install</code> only needs to be executed once, since installs the tools dependencies; after that they are ready to use.</dd>
<dd>
Use <code>PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 npm install --no-save puppeteer</code> to skip automatic downloading of Chromium. You may specify own Chromium/Chrome binary through <code>PUPPETEER_EXECUTABLE_PATH=$(which google-chrome)</code> environment variable. <b>BEWARE</b>: Puppeteer is only guaranteed to work with the bundled Chromium, use at your own risk.</dd></dl>
<h3>Using Node.js.</h3>
<p>For example:</p>
<div class="fragment"><div class="line">cd build_js/bin</div><div class="line">npm install</div><div class="line">node tests.js</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>If all tests are failed, then consider using Node.js from 8.x version (<code>lts/carbon</code> from <code>nvm</code>).</dd></dl>
<ol type="1">
<li><p class="startli">[optional] To build <code>opencv.js</code> with threads optimization, append <code>--threads</code> option.</p>
<p class="startli">For example: </p><div class="fragment"><div class="line">emcmake python ./opencv/platforms/js/build_js.py build_js --build_wasm --threads</div></div><!-- fragment --><p class="startli">The default threads number is the logic core number of your device. You can use <code>cv.parallel_pthreads_set_threads_num(number)</code> to set threads number by yourself and use <code>cv.parallel_pthreads_get_threads_num()</code> to get the current threads number.</p>
<dl class="section note"><dt>Note</dt><dd>You should build wasm version of <code>opencv.js</code> if you want to enable this optimization. And the threads optimization only works in browser, not in node.js. You need to enable the <code>WebAssembly threads support</code> feature first with your browser. For example, if you use Chrome, please enable this flag in chrome://flags.</dd></dl>
</li>
<li><p class="startli">[optional] To build <code>opencv.js</code> with wasm simd optimization, append <code>--simd</code> option.</p>
<p class="startli">For example: </p><div class="fragment"><div class="line">emcmake python ./opencv/platforms/js/build_js.py build_js --build_wasm --simd</div></div><!-- fragment --><p class="startli">The simd optimization is experimental as wasm simd is still in development.</p>
<dl class="section note"><dt>Note</dt><dd>Now only emscripten LLVM upstream backend supports wasm simd, refering to <a href="https://emscripten.org/docs/porting/simd.html">https://emscripten.org/docs/porting/simd.html</a>. So you need to setup upstream backend environment with the following command first: <div class="fragment"><div class="line">./emsdk update</div><div class="line">./emsdk install latest-upstream</div><div class="line">./emsdk activate latest-upstream</div><div class="line">source ./emsdk_env.sh</div></div><!-- fragment --></dd>
<dd>
You should build wasm version of <code>opencv.js</code> if you want to enable this optimization. For browser, you need to enable the <code>WebAssembly SIMD support</code> feature first. For example, if you use Chrome, please enable this flag in chrome://flags. For Node.js, you need to run script with flag <code>--experimental-wasm-simd</code>.</dd>
<dd>
The simd version of <code>opencv.js</code> built by latest LLVM upstream may not work with the stable browser or old version of Node.js. Please use the latest version of unstable browser or Node.js to get new features, like <code>Chrome Dev</code>.</dd></dl>
</li>
<li><p class="startli">[optional] To build wasm intrinsics tests, append <code>--build_wasm_intrin_test</code> option.</p>
<p class="startli">For example: </p><div class="fragment"><div class="line">emcmake python ./opencv/platforms/js/build_js.py build_js --build_wasm --simd --build_wasm_intrin_test</div></div><!-- fragment --><p class="startli">For wasm intrinsics tests, you can use the following function to test all the cases: </p><div class="fragment"><div class="line">cv.test_hal_intrin_all()</div></div><!-- fragment --><p class="startli">And the failed cases will be logged in the JavaScript debug console.</p>
<p class="startli">If you only want to test single data type of wasm intrinsics, you can use the following functions: </p><div class="fragment"><div class="line">cv.test_hal_intrin_uint8()</div><div class="line">cv.test_hal_intrin_int8()</div><div class="line">cv.test_hal_intrin_uint16()</div><div class="line">cv.test_hal_intrin_int16()</div><div class="line">cv.test_hal_intrin_uint32()</div><div class="line">cv.test_hal_intrin_int32()</div><div class="line">cv.test_hal_intrin_uint64()</div><div class="line">cv.test_hal_intrin_int64()</div><div class="line">cv.test_hal_intrin_float32()</div><div class="line">cv.test_hal_intrin_float64()</div></div><!-- fragment --></li>
<li><p class="startli">[optional] To build performance tests, append <code>--build_perf</code> option.</p>
<p class="startli">For example: </p><div class="fragment"><div class="line">emcmake python ./opencv/platforms/js/build_js.py build_js --build_perf</div></div><!-- fragment --><p class="startli">To run performance tests, launch a local web server in &lt;build_dir&gt;/bin folder. For example, node http-server which serves on <code>localhost:8080</code>.</p>
<p class="startli">There are some kernels now in the performance test like <code>cvtColor</code>, <code>resize</code> and <code>threshold</code>. For example, if you want to test <code>threshold</code>, please navigate the web browser to <code><a href="http://localhost:8080/perf/perf_imgproc/perf_threshold.html">http://localhost:8080/perf/perf_imgproc/perf_threshold.html</a></code>. You need to input the test parameter like <code>(1920x1080, CV_8UC1, THRESH_BINARY)</code>, and then click the <code>Run</code> button to run the case. And if you don't input the parameter, it will run all the cases of this kernel.</p>
<p class="startli">You can also run tests using Node.js.</p>
<p class="startli">For example, run <code>threshold</code> with parameter <code>(1920x1080, CV_8UC1, THRESH_BINARY)</code>: </p><div class="fragment"><div class="line">cd bin/perf</div><div class="line">npm install</div><div class="line">node perf_threshold.js --test_param_filter=&quot;(1920x1080, CV_8UC1, THRESH_BINARY)&quot;</div></div><!-- fragment --></li>
</ol>
<h2>Building OpenCV.js with Docker </h2>
<p>Alternatively, the same build can be can be accomplished using <a href="https://www.docker.com/">docker</a> containers which is often easier and more reliable, particularly in non linux systems. You only need to install <a href="https://www.docker.com/">docker</a> on your system and use a popular container that provides a clean well tested environment for emscripten builds like this, that already has latest versions of all the necessary tools installed.</p>
<p>So, make sure <a href="https://www.docker.com/">docker</a> is installed in your system and running. The following shell script should work in Linux and MacOS:</p>
<div class="fragment"><div class="line">git clone https://github.com/opencv/opencv.git</div><div class="line">cd opencv</div><div class="line">docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk emcmake python3 ./platforms/js/build_js.py build_js</div></div><!-- fragment --><p>In Windows use the following PowerShell command:</p>
<div class="fragment"><div class="line">docker run --rm --workdir /src -v &quot;$(get-location):/src&quot; &quot;emscripten/emsdk&quot; emcmake python3 ./platforms/js/build_js.py build_js</div></div><!-- fragment --><dl class="section warning"><dt>Warning</dt><dd>The example uses latest version of emscripten. If the build fails you should try a version that is known to work fine which is <code>2.0.10</code> using the following command:</dd></dl>
<div class="fragment"><div class="line">docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) emscripten/emsdk:2.0.10 emcmake python3 ./platforms/js/build_js.py build_js</div></div><!-- fragment --><p>In Windows use the following PowerShell command:</p>
<div class="fragment"><div class="line">docker run --rm --workdir /src -v &quot;$(get-location):/src&quot; &quot;emscripten/emsdk:2.0.10&quot; emcmake python3 ./platforms/js/build_js.py build_js</div></div><!-- fragment --><h3>Building the documentation with Docker</h3>
<p>To build the documentation <code>doxygen</code> needs to be installed. Create a file named <code>Dockerfile</code> with the following content:</p>
<div class="fragment"><div class="line">FROM emscripten/emsdk:2.0.10</div><div class="line"></div><div class="line">RUN apt-get update \</div><div class="line">  &amp;&amp; DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends doxygen \</div><div class="line">  &amp;&amp; rm -rf /var/lib/apt/lists/*</div></div><!-- fragment --><p>Then we build the docker image and name it <code>opencv-js-doc</code> with the following command (that needs to be run only once):</p>
<div class="fragment"><div class="line">docker build . -t opencv-js-doc</div></div><!-- fragment --><p>Now run the build command again, this time using the new image and passing <code>--build_doc</code>:</p>
<div class="fragment"><div class="line">docker run --rm -v $(pwd):/src -u $(id -u):$(id -g) &quot;opencv-js-doc&quot; emcmake python3 ./platforms/js/build_js.py build_js --build_doc</div></div><!-- fragment --> </div></div><!-- contents -->
<!-- HTML footer for doxygen 1.8.6-->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated on Fri Apr 2 2021 11:36:37 for OpenCV by &#160;<a href="http://www.doxygen.org/index.html">
<img class="footer" src="../../doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
<script type="text/javascript">
//<![CDATA[
addTutorialsButtons();
//]]>
</script>
</body>
</html>
